
#include <stdio.h>

#include "uhc.h"
#include "udc.h"
#include "sysclk.h"
#include "dev_status.h"
#include "io_mgr.h"
#include "msc.h"
#include "iap2.h"
#include "io_api.h"
#include "sd_mmc.h"
#include "twi_api.h"
#include "iic.h"
#include "common_api.h"
#include "time_mgr.h"
#include "adc_api.h"
#include "dmac.h"
#include "boot.h"
#include "wdt.h"
#include "gpbr.h"
#include "flash.h"
#include "boot_config.h"


static uint8_t power_on_proc(void)
{
    uint8_t next_status;
    //static uint8_t vbusin_result;
    static bool b_first_call = true;
    static bool b_adc_init = false;   
    
    if(b_first_call == true)
    {        
        TWI_init(TWI_PMU, IDLE_CLK);        
        ex_status.usb_cnct_status = get_hub_vbusin_state();
        
        b_first_call = false;
    }
    
    if(ex_status.usb_cnct_status == HUB_DISCNCT)
    {
        stop_discharging();
        stop_charge();
    }
    else
    {
        //if(!Is_power_on())
        //{
        start_charge();       
        start_low_power_charge();
        //}
    }

    if(b_adc_init == false)
    {
        ADC_init_adc();
        wait_ms(10);
        adc_start(ADC);
        get_adc_result(true);
        
        b_adc_init = true;
    }
    
    do
    {
        wait_ms(10);
        if(ex_status.usb_cnct_status != get_hub_vbusin_state())
        {
            if(ex_status.usb_cnct_status == HUB_CNCT)
            {
                ex_status.usb_cnct_status = HUB_DISCNCT;
            }
            else
            {
                ex_status.usb_cnct_status = HUB_CNCT;
            }
            b_adc_init = false;
            return JPM_POWER_ON;
        }
        
        adc_start(ADC);
    }while(get_adc_result(false) == false); 
  
    if(Is_power_on())
    {
        if(load_battery_power() == true)
        {
            b_led_display = true;      
        } 
        clear_battery_level_display();
    }
    else
    {
        if(ex_status.usb_cnct_status == HUB_CNCT)
        {
            b_led_display = true;
            make_led_charge_start_flag();
        }
    }
     
    //get_bat_remain_capacity();
    if((get_battery_volt() < MUI_BAT_VOLT_LOW_LIMIT) && (ex_status.usb_cnct_status == HUB_CNCT))
    {
        start_low_power_charge();
        ex_status.battery_status = BTR_PROTECT;
        ex_status.led_status = LED_LEVEL_1;
        //charge_led_init = LED_LEVEL_1;
        sd_initialized = true;
        next_status = JPM_LOW_POWER_CHARGE;
    }
    else if((get_battery_volt() < MUI_BAT_VOLT_LOW_LIMIT) && (ex_status.usb_cnct_status == HUB_DISCNCT))
    {
        next_status = JPM_DISCHARGE_PROTECT;
    }
    else
    {                                           
        if(ex_status.usb_cnct_status == HUB_CNCT)
        {             
            start_charge();
        }
        else
        {
            if(Is_charge_start())
            {
                clear_charge_start_flag();
            }
            ex_status.ex_power_type = P_SRC_NONE;       
            start_discharge();
        }    
           
        if(ex_status.ex_power_type == P_SRC_PC)
        {
            if(1)//Is_iOS6())
            {
                if(!Is_pc_flag())
                {
                    set_usb_switch(SWITCH_JPM);
                    next_status = JPM_CONNECT_IPHONE;
                    ex_status.ex_power_type = P_SRC_PC_PRE;
                }
                else
                {
                    clear_pc_flag();
                    set_usb_switch(SWITCH_HUB);
                    next_status = JPM_CONNECT_PC;
                }
            }

            else
            {
                set_usb_switch(SWITCH_HUB);
                next_status = JPM_CONNECT_PC;
            }
            
        }
        else //connect to external power source or P_SRC_NONE
        {
            if(1)//Is_iOS6())
            {
                if(Is_pc_flag())
                {
                    clear_pc_flag();
                }
            }
            set_usb_switch(SWITCH_JPM);
            next_status = JPM_CONNECT_IPHONE;
        }
        
        get_bat_remain_capacity();
        if(!Is_power_on())
        {
            make_power_on_flag();          
        }
              
        init_work_mode();       
        init_modify_code();       
        get_pwd_need_info();
        get_part_number();
    }       
    
    start_check_timer();    
    return next_status;
}

static uint8_t connect_to_pc_proc(void)
{
    if((b_need_to_verify == false) || ((b_need_to_verify == true) && (Is_pc_verified() == true)))
    {
        b_verified = true;
        clear_pc_verified_flag();
      
        udd_enable();
              
    }
    ex_status.mcu_status = MCU_WORK;
    //reset_check_adc();
    reset_check_timer();
    g_interface_num = 1;
    start_standby_timer();
    return JPM_NORMAL_MSC;
}

static uint8_t normal_msc_proc(void)
{
    uint8_t adc_detect_result;
    
    if(ex_status.usb_role == USB_CONFIGED)
    {
        if(!msc_process(true))
        {
            restore_battery_power(false, false);
            return JPM_RESET;
        }
    } 
    
    if(Is_vbusin_changed())
    {
        restore_battery_power(false, false);
        return JPM_RESET;
    }
    
    if(Is_button_pressed())
    {
        start_led_timer();
    }
    
    adc_detect_result = power_detect();
            
    if(adc_detect_result == 2)
    {
        return JPM_WARNING;
    }
            
    else if(adc_detect_result == 3)
    {
        return JPM_CHARGE_PROTECT;
    }
    
    if(Is_standby_time_over())
    {
        if(sysclk_run_fastest == true)
        {
            //sd_mmc_init();
            //sdio_power_down();
            //wait_ms(30);  
            enter_stand_by_mode();
        }
    }
    
    return JPM_NORMAL_MSC;
}

static uint8_t connect_to_iphone_proc(void)
{
    uhd_enable();
    ex_status.usb_role = USB_HOST;
    ex_status.mcu_status = MCU_WORK;
    //reset_check_adc();
    reset_check_timer();
    g_interface_num = 2;
    //while(!b_usb_switch);
    //udd_enable();
    //while(1);
    start_sleep_timer();
    if(ex_status.usb_cnct_status == HUB_CNCT)
    {
        if(1)//Is_iOS6())
        {
            if(ex_status.ex_power_type == P_SRC_PC_PRE)
            {
                start_re_pc_timer();
            }
        }
        
        g_jpm_start_stop_charge = 2;
        return JPM_CHARGE_MODE;
    }
    else
    {        
        if(Is_charge())
        {
            g_jpm_start_stop_charge = 2;
            return JPM_GREEN_MODE;
        }
        else
        {
            g_jpm_start_stop_charge = 1;
            return JPM_RED_MODE;
        }     
    }
}
#ifdef SUPPORT_OTG
static uint8_t connect_to_otg_proc(void)
{
    uhd_enable();
    ex_status.usb_role = USB_HOST;
    ex_status.mcu_status = MCU_WORK;
    //reset_check_adc();
    reset_check_timer();
    g_interface_num = 2;

    if(ex_status.usb_cnct_status == HUB_CNCT)
    {
        if(ex_status.ex_power_type == P_SRC_PC_PRE)
        {
            start_re_pc_timer();
        }
        g_jpm_start_stop_charge = 2;
        return JPM_CHARGE_MODE;
    }
    else
    {        
        if(Is_charge())
        {
            g_jpm_start_stop_charge = 2;
            return JPM_GREEN_MODE;
        }
        else
        {
            g_jpm_start_stop_charge = 1;
            return JPM_RED_MODE;
        }     
    }
}
#endif
static uint8_t msc_charge_mode_proc(void)
{  
    uint8_t adc_detect_result;
    uint8_t charge_mode_sel;
    static  bool b_charge_protect_flag = false;
    static bool b_first = true;
    
    if(Is_re_pc_time_over() == true)//Is_iOS6())
    {
        stop_re_pc_timer();
        if(ex_status.ex_power_type == P_SRC_PC_PRE)
        {                     
            if((b_need_to_verify == false) || (ex_status.usb_role != USB_CONFIGED))
            {               
                restore_pc_flag();
                restore_battery_power(true, true);
                return JPM_RESET;
            }

            else
            {
                if(b_verified == false)
                {
                    start_applaunch_timer();
                }
            }
        }
    }

    if(Is_applaunch_time_over() == true)
    {
        restore_pc_flag();
        restore_battery_power(true, true);
        return JPM_RESET;
    }
    
    if((b_need_to_verify == true) && (b_verified == true))
    {
        stop_applaunch_timer();
    }
    
    if(ex_status.usb_role == USB_ROLE_SWITCH)
    {
        udd_enable();
        //ex_status.usb_role = USB_DEVICE;
        //b_usb_switch = false;
    }
    if(g_jpm_iap_start == 1)
    {
        if(!iap2_start_sequence())
        {
            restore_battery_power(false, false);
            return JPM_RESET;
        }
    }
    
    adc_detect_result = power_detect();
    
    if(adc_detect_result == 2)
    {
        return JPM_WARNING;
    }
    
    if(g_jpm_start_mfi == MFI_AUTH_COMPLETE)
    {
        start_standby_timer();
        if(b_charge_configued == false)
        {
            if(ex_status.ex_power_type == P_SRC_0P5A)
            {
                charge_mode_sel = CHARGE_MODE_HALF;
            }
            else if(ex_status.ex_power_type == P_SRC_PC_PRE)
            {
                charge_mode_sel = CHARGE_MODE_HALF;
            }
            else
            {
                charge_mode_sel = CHARGE_MODE_NORMAL;
            }

            if(iap2_set_charge_config(charge_mode_sel) == false)
            {
                restore_battery_power(false, false);
                return JPM_RESET;
            }
            else
            {
                b_charge_configued = true;
                if(ex_status.ex_power_type == P_SRC_PC_PRE)
                {
                    if(b_need_to_verify == false)
                    {
                        restore_pc_flag();
                        restore_battery_power(true, true);
                        return JPM_RESET;
                    }
                }
            }
        }                
                       
        if(adc_detect_result == 3)
        {
            if(b_charge_protect_flag == false)
            {
                if(ex_status.ex_power_type == P_SRC_0P5A)
                {
                    return JPM_CHARGE_PROTECT;
                }
                else
                {
                    if(iap2_set_charge_config(CHARGE_MODE_HALF) == false)
                    {
                        restore_battery_power(false, false);
                        return JPM_RESET;
                    }
                    b_charge_protect_flag = true;
                }
            }
            if(Is_sleep_time_over())
            {
                return JPM_CHARGE_IDLE; 
            }
        }
        
        else if(adc_detect_result == 1)
        {
            if(b_charge_protect_flag == true)
            {
                if(ex_status.ex_power_type != P_SRC_0P5A)
                {
                    if(iap2_set_charge_config(CHARGE_MODE_NORMAL) == false)
                    {
                        restore_battery_power(false, false);
                        return JPM_RESET;
                    }
                }
                b_charge_protect_flag = false;
            }
            if(Is_sleep_time_over())
            {
                return JPM_CHARGE_IDLE; 
            }
        }
        
        if(Is_standby_time_over())
        {
            if(sysclk_run_fastest == true)
            {
                enter_stand_by_mode();
            }
        }             
    } 
    
    else if(Is_sleep_time_over())
    {
        if(ex_status.ele_cur_status == NO_CHARGE_CUR)
        {
            if(b_first)
            {
                //sleep_timer_start = get_system_time();
                start_cur_timer();
                b_first = false;
            }
            else
            {
                //sleep_timer_now = get_system_time();
                if(Is_cur_time_over(2000))
                {
                    stop_cur_timer();
                    return JPM_CHARGE_IDLE;                
                }
            }
        }
        else
        {
            stop_cur_timer();
            b_first = true;
            reset_sleep_timer();
        }
    }
    
    if(!msc_process(false))
    {
        restore_battery_power(false, false);
        return JPM_RESET;
    }  

    if(Is_vbusin_changed())
    {
        restore_battery_power(false, false);
        return JPM_RESET;
    }
    
    if(Is_button_pressed())
    {
        reset_sleep_timer();
        start_led_timer();
    }
  
    return JPM_CHARGE_MODE;
}

static uint8_t msc_green_mode_proc(void)
{
    static bool b_first = true;
    uint8_t adc_detect_result;
    //uint32_t sleep_timer_start;
    //uint32_t sleep_timer_now;
    
    
    if(ex_status.usb_role == USB_ROLE_SWITCH)
    {
        udd_enable();
        //ex_status.usb_role = USB_DEVICE;
        reset_sleep_timer();
        //b_usb_switch = false;
    }
       
    if(g_jpm_iap_start == 1)
    {
        if(!iap2_start_sequence())
        {
            restore_battery_power(false, false);
            return JPM_RESET;
        }
    }
    
    adc_detect_result = power_detect();
    
    if(adc_detect_result == 2)
    {
        return JPM_WARNING;
    }
      
    if(g_jpm_start_mfi == MFI_AUTH_COMPLETE)
    {
        start_standby_timer();
        if(b_charge_configued == false)
        {
            if(iap2_set_charge_config(CHARGE_MODE_FULL) == false)
            {
                restore_battery_power(false, false);
                return JPM_RESET;
            }
            else
            {
                b_charge_configued = true;
                stop_delay_timer();
                start_sleep_timer();
            }
        }
        
        if(adc_detect_result == 3)
        {
            return JPM_DISCHARGE_PROTECT;
        }
        
        if(Is_standby_time_over())
        {
            if(sysclk_run_fastest == true)
            {
                enter_stand_by_mode();
            }
        }        
    }
    if(!msc_process(false))
    {
        restore_battery_power(false, false);
        return JPM_RESET;
    }  
          
    if(Is_vbusin_changed())
    {
        restore_battery_power(true, true);
        return JPM_RESET;
    }
    
    if(Is_button_pressed())
    {
        reset_sleep_timer();
        start_led_timer();
    }
 
#ifndef _NO_SLEEP_    
    if(Is_sleep_time_over())
    {       
        if(ex_status.usb_role == USB_CONFIGED)
        {
            stop_cur_timer();
            b_first = true;
            reset_sleep_timer();
            if(PIO_read_bit(PUSH_BUTTON_PIO, PUSH_BUTTON_PIO_IDX) == PUSH_BUTTON_PRESS)
            {
                b_button_pressed_before_sleep = true;
            }
            else
            {
                b_button_pressed_before_sleep = false;
            }
            return JPM_DISCHARGE_IDLE;
        }
        else
        {
            if(ex_status.ele_cur_status == NO_CHARGE_CUR)
            {
                if(b_first)
                {
                    //sleep_timer_start = get_system_time();
                    start_cur_timer();
                    b_first = false;
                }
                else
                {
                    //sleep_timer_now = get_system_time();
                    if(Is_cur_time_over(2000))
                    {
                        stop_cur_timer();
                        return JPM_SLEEP;                
                    }
                }
            }
            else
            {          
                stop_cur_timer();
                b_first = true;
                stop_sleep_timer();
                start_delay_timer();
            }
        }
    }
    
    if(Is_delay_time_over(600000))
    {
        stop_delay_timer();
        start_sleep_timer();
    }
#endif
          
    if(get_charge_state() == 1)
    {
        stop_delay_timer();
        reset_sleep_timer();
        start_sleep_timer();
        if(g_jpm_start_mfi == MFI_AUTH_COMPLETE)
        {            
            if(iap2_set_charge_config(CHARGE_MODE_OFF) == false)
            {
                restore_battery_power(false, false);
                return JPM_RESET;
            }
            else
            {
                return JPM_RED_MODE;
            }
        }
        else
        {
            return JPM_RED_MODE;
        }
    }
    
    return JPM_GREEN_MODE;
}///////////////////////////////////////////////////

static uint8_t msc_red_mode_proc(void)
{
    uint8_t adc_detect_result;
  
    if(ex_status.usb_role == USB_ROLE_SWITCH)
    {
        udd_enable();
        //ex_status.usb_role = USB_DEVICE;
        reset_sleep_timer();
       // b_usb_switch = false;
    }
              
    if(g_jpm_iap_start == 1)
    {
        if(!iap2_start_sequence())
        {
            restore_battery_power(false, false);
            return JPM_RESET;
        }
    }
    
    adc_detect_result = power_detect();
    
    if(adc_detect_result == 2)
    {
        return JPM_WARNING;
    }
    
    if(g_jpm_start_mfi == MFI_AUTH_COMPLETE)
    {
        start_standby_timer();
        if(b_charge_configued == false)
        {
            if(iap2_set_charge_config(CHARGE_MODE_OFF) == false)
            {
                restore_battery_power(false, false);
                return JPM_RESET;
            }
            else
            {
                b_charge_configued = true;
            }
        }
                      
        if(adc_detect_result == 3)
        {
            return JPM_DISCHARGE_PROTECT;
        }
        
        if(Is_standby_time_over())
        {
            if(sysclk_run_fastest == true)
            {
                enter_stand_by_mode();
            }
        }      
    }  
   
    if(!msc_process(false))
    {
        restore_battery_power(false, false);
        return JPM_RESET;
    }  
          
    if(Is_vbusin_changed())
    {
        restore_battery_power(true, true);
        return JPM_RESET;
    }
    
    if(Is_button_pressed())
    {
        reset_sleep_timer();
        start_led_timer();
    }
#ifndef _NO_SLEEP_         
    if(Is_sleep_time_over())
    {
        return JPM_SLEEP;        
    }
#endif
          
    if(get_charge_state() == 2)
    {
        reset_sleep_timer();
        if(g_jpm_start_mfi == MFI_AUTH_COMPLETE)
        {            
            if(iap2_set_charge_config(CHARGE_MODE_FULL) == false)
            {
                restore_battery_power(false, false);
                return JPM_RESET;
            }
            else
            {
                return JPM_GREEN_MODE;
            }
        }
        else
        {
            return JPM_GREEN_MODE;
        } 
    } 
    
    return JPM_RED_MODE;
}

static uint8_t enter_sleep_proc(void)
{
    //uint8_t switch_state;
    
    enter_sleep_mode(true);
    
    //after wake-up 
#ifdef _VIRTRUAL_DISCHARGE_
    if(ex_status.battery_power != 0)
    {
        ex_status.battery_power -= 1;
    }
#endif   
    
    PIO_input_config_api(PUSH_BUTTON_PIO, 0, 0, PUSH_BUTTON_PIO_IDX);
    PIO_input_config_api(HUB_CNCT_PIO, 0, 0, HUB_CNCT_PIO_IDX);
    PIO_input_config_api(CHGE_SWITCH_PIO, 0, 0, CHGE_SWITCH_PIO_IDX);
    
    pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz);
    pmc_switch_mck_to_mainck(PMC_PCK_PRES_CLK_1);
        
    pmc_osc_disable_xtal(0);
    pmc_disable_pllack();
        
    //start_system_timer(4000000);
        
    if(PIO_read_bit(HUB_CNCT_PIO, HUB_CNCT_PIO_IDX) == HUB_VBUS_ON)
    {
        restore_battery_power(true, true);
        RSTC->RSTC_CR = (0xa5000000 | 0x01 | 0x04);
    }    
    
    else if(((PIO_read_bit(CHGE_SWITCH_PIO, CHGE_SWITCH_PIO_IDX) == SWITCH_CHARGE) && (ex_status.switch_status == SWT_OFF)) || 
            ((PIO_read_bit(CHGE_SWITCH_PIO, CHGE_SWITCH_PIO_IDX) == SWITCH_NO_CHARGE) && (ex_status.switch_status == SWT_ON)))
    {
        restore_battery_power(false, false);
        RSTC->RSTC_CR = (0xa5000000 | 0x01 | 0x04);
    }
    
    else
    {
        restore_battery_power(true, false);
        RSTC->RSTC_CR = (0xa5000000 | 0x01 | 0x04);
    }
    
    return JPM_SLEEP;
}

static uint8_t discharge_protect_proc(void)
{
    enter_sleep_mode(false);        

    restore_battery_power(true, true);
    RSTC->RSTC_CR = (0xa5000000 | 0x01 | 0x04);
        
    return JPM_RESET;
}

static uint8_t charge_idle_proc(void)
{
    static bool b_re_init = false;
    uint8_t adc_detect_result;
    
    if(b_re_init == false)
    {
        enter_light_sleep_mode();       
        b_re_init = true;
    }
    
    if(Is_vbusin_changed())
    {
        restore_battery_power(false, false);
        return JPM_RESET;
    }
    
    if(Is_button_pressed())
    {
        restore_battery_power(true, false);
        return JPM_RESET;
    }
    
    adc_detect_result = power_detect();
            
    if(adc_detect_result == 2)
    {
        return JPM_WARNING;
    }
    
    /*
    else if(adc_detect_result == 3)
    {
        return JPM_CHARGE_PROTECT;
    }
    */
    
    return JPM_CHARGE_IDLE;
}

static uint8_t discharge_idle_proc(void)
{
    //static bool b_first = true;
    static bool b_re_init = false;
    uint8_t adc_detect_result;
    //uint32_t sleep_timer_start;
    //uint32_t sleep_timer_now;   
    
    if(b_re_init == false)
    {
        enter_light_sleep_mode();       
        b_re_init = true;
    }
    
    if(Is_vbusin_changed())
    {
        restore_battery_power(true, true);
        return JPM_RESET;
    }
    
    if(b_button_pressed_before_sleep == false)
    {
        if(Is_button_pressed())
        {
            restore_battery_power(true, false);
            return JPM_RESET;
        }
    }
    else
    {
        if(PIO_read_bit(PUSH_BUTTON_PIO, PUSH_BUTTON_PIO_IDX) == PUSH_BUTTON_NO_PRESS)
        {
            restore_battery_power(false, false);
            return JPM_RESET;
        }
    }
    
    if(get_charge_state() == 1)
    {
        restore_battery_power(false, false);
        return JPM_RESET;
    }
  
    /*if(ex_status.ele_cur_status == NO_CHARGE_CUR)
    {
        if(b_first)
        {
            start_cur_timer();
            b_first = false;
        }
        else
        {
            if(Is_cur_time_over(5000))
            {
                stop_cur_timer();
                return JPM_SLEEP;                
            }
        }
    }
    else
    {
        stop_cur_timer();        
        b_first = true;
    }*/
    
    adc_detect_result = power_detect();
            
    if(adc_detect_result == 2)
    {
        return JPM_WARNING;
    }
            
    else if(adc_detect_result == 3)
    {
        return JPM_DISCHARGE_PROTECT;
    }
    
    return JPM_DISCHARGE_IDLE;
}

static uint8_t charge_protect_proc(void)
{
    static bool b_close = false;
    uint8_t adc_detect_result;
    
    if(b_close == false)
    {
        //close each module and re-init sysclk to 4MB osc
        enter_light_sleep_mode();     
        
        b_close = true;
    }
    
    if(Is_vbusin_changed())
    {
        restore_battery_power(false, false);
        return JPM_RESET;
    }
    
    if(Is_button_pressed())
    {
        start_led_timer();
    }
    
    adc_detect_result = power_detect();
    
    if(adc_detect_result == 2)
    {
        return JPM_WARNING;
    }
    else if(adc_detect_result == 1)
    {
        if(!Is_power_on())
        {
            make_power_on_flag();          
        } 
        restore_battery_power(false, false);
        return JPM_RESET;
    }
  
    return JPM_CHARGE_PROTECT;
}

static uint8_t low_power_charge_proc(void)
{
    static bool b_first_call = false;
    uint16_t tmp_battery_volt;
    
    start_low_power_charge();
    
    if(Is_vbusin_changed())
    {
        //restore_battery_power(false, false);
        return JPM_RESET;
    }
    
    if(Is_button_pressed())
    {
        start_led_timer();
    }
    
    if(b_first_call == false)
    {
        b_first_call = true;
        adc_start(ADC);
        reset_check_timer();
    }
    
    if(Is_check_time_over())
    {      
        if(get_adc_result(false) == true)
        {
            tmp_battery_volt = get_battery_volt();
            if(get_battery_volt() > MUI_BAT_VOLT_LOW_LIMIT)
            {
                if(!Is_power_on())
                {
                    make_power_on_flag();          
                } 
                //get_bat_remain_capacity();
                if(tmp_battery_volt > BAT_VOLTAGE_335V)
                {
                    update_power_state();
                    restore_battery_power(false, false);
                    return JPM_RESET;
                }
            }
        }
        adc_start(ADC);
        reset_check_timer();
    }
    
    return JPM_LOW_POWER_CHARGE;
}

static uint8_t warning_proc(void)
{
    static uint8_t warning_step = 0;
    static bool b_led_on = false;
    //static uint32_t warning_start_line;
    uint8_t adc_detect_result;  
    
    if(warning_step == 0)
    {
        stop_check_timer();
        //close each module and re-init sysclk to 4MB osc
        enter_light_sleep_mode();
        
        PIO_set_bit(HUB_SWITCH_PIO, HUB_SWITCH_PIO_IDX);
             
        //start led warning flick
        //start_charge_led_timer();
        start_next_flick();
        turn_all_led(LED_ON);
        b_led_on = true;
        
        //stop_discharging();
        //stop_charge();
        
        //warning_start_line = get_system_time();       
        start_temp_timer();
        warning_step = 1;
    }
    
    if(Is_vbusin_changed())
    {
        if(ex_status.usb_cnct_status == HUB_CNCT)
        {
            restore_battery_power(true, true);
        }
        else
        {
            restore_battery_power(false, false);
        }
        return JPM_RESET;
    }
    
    if(Is_flick_time_over())
    {
        stop_next_flick();
        if(b_led_on == true)
        {
            turn_all_led(LED_OFF);
            b_led_on = false;
        }
        else
        {
            turn_all_led(LED_ON);
            b_led_on = true;
        }
        start_next_flick();
    }
    
    if(warning_step == 1)
    {
        if(Is_temp_time_over(15000) == false)
        {
            return JPM_WARNING;
        }

        stop_discharging();
        warning_step = 2;
        return JPM_WARNING;
    }
    
    if(warning_step == 2)
    {
        stop_charge();
        //warning_start_line = get_system_time();
        reset_temp_timer();
        warning_step = 3;
        return JPM_WARNING;
    }
    
    if(warning_step == 3)
    {
        if(Is_temp_time_over(1000) == false)
        {
            return JPM_WARNING;
        }        
        warning_step = 4;
    }       

    if(warning_step == 4)
    {
        reset_check_adc();
        warning_step = 5;
        return JPM_WARNING;
    }
    
    if(warning_step == 5)
    {
        get_adc_result(true);
        adc_start(ADC);
        warning_step = 6;
        return JPM_WARNING;
    }
    
    if(warning_step == 6)
    {
        if(get_adc_result(false) == false)
        {
            adc_start(ADC);
            return JPM_WARNING;
        }
        
        warning_step = 7;
        return JPM_WARNING;
    }
    
    if(warning_step == 7)
    {
        if(ex_status.usb_cnct_status == HUB_CNCT)
        {             
            start_charge();
        }
        else
        { 
            start_discharge();
        }   
    
        start_check_timer();
        warning_step = 8;
        return JPM_WARNING;
    }
    
    adc_detect_result = power_detect();
    
    if(adc_detect_result == 2)
    {
        //stop_temp_timer();
        stop_check_timer();
        //warning_start_line = get_system_time();
        reset_temp_timer();
        warning_step = 1;
    }
    else if(adc_detect_result == 1)
    {
        stop_next_flick();
        stop_temp_timer();
        restore_battery_power(false, false);
        return JPM_RESET;
    }
  
    return JPM_WARNING;
}


int main(void)
{   
    io_init(); 
    //sysclk_init();   
    status_init();
    boot_load_proc();      
    
    cpu_irq_enable();          
    start_system_timer(IDLE_CLK);       

#ifdef USED_J_TAG	
    wdt_disable(WDT);
#else    
    start_wdt(); 
#endif

    while(1)
    {
 #ifdef USED_J_TAG	
 #else    
      	feed_dog();
 #endif
       
        if(g_jpm_status.current == JPM_POWER_ON)
        {
            update_jpm_status(power_on_proc());
            continue;
        }
       
        if(b_led_display == true)
        {
            b_led_display = false;
            start_led_timer();
        }
        
        charge_led_proc();
        
        switch(g_jpm_status.current)
        {        
        case JPM_CONNECT_PC:          
          update_jpm_status(connect_to_pc_proc());
          break;
          
        case JPM_NORMAL_MSC:
          update_jpm_status(normal_msc_proc());                                
          break;
#ifdef SUPPORT_OTG
        case JPM_CONNECT_OTG:
          update_jpm_status(connect_to_otg_proc());
          break;
#endif
        case JPM_CONNECT_IPHONE:
          update_jpm_status(connect_to_iphone_proc());
          break;

        case JPM_CHARGE_MODE:
          update_jpm_status(msc_charge_mode_proc());
          break;
          
        case JPM_GREEN_MODE:
          update_jpm_status(msc_green_mode_proc());  
          break;
          
        case JPM_RED_MODE:
          update_jpm_status(msc_red_mode_proc());
          break;
          
        case JPM_SLEEP:
          update_jpm_status(enter_sleep_proc());
          break;
          
        case JPM_DISCHARGE_IDLE:
          update_jpm_status(discharge_idle_proc());
          break;
          
        case JPM_CHARGE_IDLE:
          update_jpm_status(charge_idle_proc());
          break;
          
        case JPM_CHARGE_PROTECT:
          update_jpm_status(charge_protect_proc());
          break;
          
        case JPM_DISCHARGE_PROTECT:
          update_jpm_status(discharge_protect_proc());
          break;
          
        case JPM_WARNING:
          update_jpm_status(warning_proc());
          break;
          
        case JPM_LOW_POWER_CHARGE:
          update_jpm_status(low_power_charge_proc());
          break;
          
        case JPM_RESET:
        default:        
          reset_system();
          break;
        }
    }
}





